package com.justgame.project.service.system.service;

import com.justgame.project.cloud.common.constant.Const;
import com.justgame.project.cloud.common.exception.Exc;
import com.justgame.project.cloud.common.util.FileUtils;
import com.justgame.project.cloud.common.util.IdUtils;
import com.justgame.project.cloud.common.util.ObjUtil;
import com.justgame.project.cloud.common.util.ShiroUtils;
import com.justgame.project.service.api.dto.SysFileInfoDTO;
import com.justgame.project.service.api.entity.SysFileInfo;
import com.justgame.project.service.system.mapper.SysFileInfoMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

@Service
@Transactional
public class SysFileInfoService {

    @Resource
    private SysFileInfoMapper sysFileInfoMapper;

    public List<SysFileInfo> getMineFiles() {
        SysFileInfoDTO dto = new SysFileInfoDTO();
        ShiroUtils.setEntityUserId(dto);
        return sysFileInfoMapper.selectList(dto);
    }

    public int realDelete(SysFileInfoDTO sysFileInfo) {
        return sysFileInfoMapper.delete(sysFileInfo);
    }

    public void deleteFiles(List<String> paths) {
        if (paths == null || paths.size() == 0) {
            throw new Exc("请选择你要删除的文件！");
        }
        SysFileInfoDTO infoDTO = new SysFileInfoDTO();
        infoDTO.setPathList(paths);
        /* 获取要删除的文件 */
        List<SysFileInfo> want2DelList = sysFileInfoMapper.selectList(infoDTO);
        /* 不为空 */
        if (want2DelList != null && want2DelList.size() > 0) {
            /* 如果不是管理员，就检查当前想要删除的文件是否有权删除 */
            if (!ShiroUtils.isAdmin()) {
                /* 初始变量 */
                AtomicBoolean isPass = new AtomicBoolean(true);

                /* 获取当前操作人信息 */
                String userId = ShiroUtils.getUserId();
                if (userId == null) {
                    throw new Exc(Const.CODE_TOKEN_OUTDATED_CHINESE, Const.CODE_TOKEN_OUTDATED);
                }

                want2DelList.forEach(info -> {
                    if (info.getCreateUser() != null && !info.getCreateUser().equals(userId)) {
                        isPass.set(false);
                    }
                });

                if (!isPass.get()) {
                    throw new Exc("操作失败！系统无法删除不属于您的文件！");
                }
            }

            /* 收集Path */
            List<String> pathList = want2DelList.stream().map(SysFileInfo::getPath).collect(Collectors.toList());

            /* 物理删除文件 */
            FileUtils.deleteFiles(pathList);

            SysFileInfoDTO newDto = new SysFileInfoDTO();
            newDto.setPathList(pathList);
            ObjUtil.inject(newDto, false);
            /* 更新数据库 */
            sysFileInfoMapper.delete(newDto);
        }
    }

    public Boolean deleteFile(SysFileInfoDTO dto) {
        if (StringUtils.isBlank(dto.getId()) && StringUtils.isBlank(dto.getPath())) {
            throw new Exc("请选择你要删除的文件！");
        }

        /* 获取要删除的文件 */
        List<SysFileInfo> want2DelList = sysFileInfoMapper.selectList(dto);

        /* 不为空 */
        if (want2DelList != null && want2DelList.size() > 0) {
            /* 如果不是管理员，就检查当前想要删除的文件是否有权删除 */
            if (!ShiroUtils.isAdmin()) {
                /* 初始变量 */
                AtomicBoolean isPass = new AtomicBoolean(true);

                /* 获取当前操作人信息 */
                String userId = ShiroUtils.getUserId();
                if (userId == null) {
                    throw new Exc(Const.CODE_TOKEN_OUTDATED_CHINESE, Const.CODE_TOKEN_OUTDATED);
                }

                want2DelList.forEach(info -> {
                    if (info.getCreateUser() != null && !info.getCreateUser().equals(userId)) {
                        isPass.set(false);
                    }
                });

                if (!isPass.get()) {
                    throw new Exc("操作失败！系统无法删除不属于您的文件！");
                }
            }

            /* 收集Path */
            List<String> paths = want2DelList.stream().map(SysFileInfo::getPath).collect(Collectors.toList());

            /* 物理删除文件 */
            FileUtils.deleteFiles(paths);

            SysFileInfoDTO newDto = new SysFileInfoDTO();
            newDto.setPathList(paths);
            ObjUtil.inject(newDto, false);
            /* 更新数据库 */
            return sysFileInfoMapper.delete(newDto) > 0;
        } else {
            throw new Exc("你要删除的文件不存在！");
        }
    }

    public Integer Insert(SysFileInfo file) {
        ObjUtil.inject(file, true);
        return sysFileInfoMapper.insertOne(file);
    }

    public void save(SysFileInfo file, List<Map<String, Object>> files) {
        String userId = ShiroUtils.getUserId();
        /* 装配所属用户 */
        if (StringUtils.isNotBlank(userId)) {
            file.setUserId(userId);
        } else {
            file.setUserId("");
        }
        file.setCreateDate(new Date());
        for (Map<String, Object> f : files) {
            file.setId(IdUtils.create(18));
            file.setPath((String) f.get("filePath"));
            file.setSuffix((String) f.get("fileSuffix"));
            /* 该字段Object原型为int，所以用StringValueOf */
            file.setSize(String.valueOf(f.get("fileSize")));
            file.setName((String) f.get("fileName"));
            if (Insert(file) == 0) {
                throw new RuntimeException("保存文件信息失败");
            }
        }
    }
}
